package com.young.msg.service.impl;

import com.young.common.util.CollectionUtil;
import com.young.common.util.CommonUtil;
import com.young.common.core.dal.service.IDataAccessService;
import com.young.common.util.DateUtil;
import com.young.common.util.Page;
import com.young.interfaces.log.annotation.Log;
import com.young.interfaces.ums.model.User;
import com.young.interfaces.ums.service.IUmsOutService;
import com.young.msg.model.SiteLetter;
import com.young.msg.model.SiteLetterReceive;
import com.young.msg.model.enums.ESiteLetterReadStatusEnum;
import com.young.msg.service.ISiteLetterReceiveService;
import com.young.msg.service.ISiteLetterService;
import com.young.msg.util.MsgPojoFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
* 站内信收取服务实现
* Created by wangjiyu on 2021-10-31.
*/
@Service("siteLetterReceiveService")
public class SiteLetterReceiveServiceImpl implements ISiteLetterReceiveService {

    @Resource(name = "dataAccessService")
    IDataAccessService dataAccessService;//数据层服务
    /**
     * 用户服务
     */
    @Autowired
    private IUmsOutService umsOutService;
    /**
     * 站内信服务
     */
    @Autowired
    private ISiteLetterService siteLetterService;

    private static final Logger logger = LoggerFactory.getLogger(SiteLetterReceiveServiceImpl.class);

    private static final String MAPPER = "com.young.msg.mapper.siteLetterReceive";//mapper的namespace

    /**
     * 查询用户上一次收信时间
     *
     * @param userId 用户id
     * @return
     */
    @Log("查询用户上一次收信时间")
    @Override
    public Date getUserLastReceiveTime(String userId) {
        return dataAccessService.getObject(MAPPER + ".getUserLastReceiveTime", userId);
    }

    //获取数据列表
    @Log("查询站内信收取列表")
    @Override
    public List<SiteLetterReceive> getList(SiteLetterReceive obj) {
        return dataAccessService.getList(MAPPER + ".getList", obj);
    }

    //获取数据列表(分页)
    @Log("分页查询站内信收取列表")
    @Override
    public List<SiteLetterReceive> getPage(SiteLetterReceive obj, Page page) {
        return dataAccessService.getList(MAPPER + ".getList", obj, page);
    }

    //查询单条
    @Log("查询站内信收取")
    @Override
    public SiteLetterReceive get(Long id) {
        return dataAccessService.getObject(MAPPER + ".get", id);
    }

    //统计数量
    @Log("统计站内信收取数量")
    @Override
    public int count(SiteLetterReceive obj) {
        return dataAccessService.getObject(MAPPER + ".count", obj);
    }

    //修改
    @Log("修改站内信收取")
    @Override
    public int update(SiteLetterReceive obj) {
        return dataAccessService.update(MAPPER + ".update", obj);
    }

    //批量删除
    @Log("批量删除站内信收取")
    @Override
    public int delete(Long[] idArr) {
        int i = 0;
        for(Long id : idArr){
            i += this.delete(id);
        }
        return i;
    }

    //删除单条
    @Log("删除站内信收取")
    @Override
    public int delete(Long id) {
        return dataAccessService.delete(MAPPER + ".delete", id);
    }

    //插入
    @Log("新增站内信收取")
    @Override
    public int insert(SiteLetterReceive obj) {
        if (obj.getCreateTime() == null) {
            obj.setCreateTime(new Date());
        }
        if (obj.getUpdateTime() == null) {
            obj.setUpdateTime(new Date());
        }
        return dataAccessService.insert(MAPPER + ".insert", obj);
    }

    //批量插入
    @Log("批量新增站内信收取")
    @Override
    public int batchInsert(List<SiteLetterReceive> list) {
        int i = 0;
        for(SiteLetterReceive item : list){
            i += this.insert(item);
        }
        return i;
    }

    /**
     * 设为已读
     *
     * @param idList
     * @return
     */
    @Log("设为已读")
    @Override
    public int readStatus(List<Long> idList) {
        Map<String, Object> map = new HashMap<>();
        map.put("idList", idList);
        map.put("readStatus", ESiteLetterReadStatusEnum.READ.type);
        return dataAccessService.update(MAPPER + ".updateReadStatus", map);
    }

    /**
     * 收取信件
     *
     * @param receiverUserId 收信人
     */
    @Log("收取信件")
    @Override
    public void receiveLetter(String receiverUserId) {
        // 查询用户信息
        User user = umsOutService.getUser(receiverUserId);
        if (user == null) {
            logger.error("[收取信件] 查询用户为空,无法收信,userId={}", receiverUserId);
            return;
        }
        // 查询用户最近收信时间
        Date lastTime = this.getUserLastReceiveTime(receiverUserId);
        logger.info("[收取信件] 用户上一次收信时间={}", DateUtil.dateFormat(lastTime));

        // 如果用户没有收过信, 从用户创建时间开始收
        if (lastTime == null) {
            lastTime = user.getCreateTime();
            logger.info("[收取信件] 用户上一次收信时间为空,使用用户注册时间={}", DateUtil.dateFormat(lastTime));
        }

        if (lastTime == null) {
            logger.warn("[收取信件] 用户上一次收信时间和注册时间都为空,不支持收信");
            return;
        }

        // 本次收取时间, 收取从上一次到现在的信
        Date receiveTime = new Date();

        // 查询上一次收信时间之后的新信件(全员信)
        List<SiteLetter> letterList = siteLetterService.getReceiveLetterByTime(lastTime, receiveTime);
        if (letterList == null) {
            letterList = new ArrayList<>();
        }
        // 查询指定收件人为自己的信件
        List<SiteLetter> userLetter = siteLetterService.getUserReceiveLetter(receiverUserId, lastTime, receiveTime);
        if (CollectionUtil.isNotEmpty(userLetter)) {
            letterList.addAll(userLetter);
        }

        if (CollectionUtil.isEmpty(letterList)) {
            logger.info("[收取信件] 根据时间获取待收信件为空,时间={}~{}", DateUtil.dateFormat(lastTime), DateUtil.dateFormat(receiveTime));
            return;
        }

        // 构造收信对象
        List<SiteLetterReceive> receiveList = letterList.stream()
                .map(item -> MsgPojoFactory.buildSiteLetterReceive(item, receiverUserId, user.getName(), receiveTime))
                .collect(Collectors.toList());

        // 批量插入收信
        int count = this.batchInsert(receiveList);

        logger.info("[收取信件] 本次成功收取信件数={},用户={}", count, receiverUserId);
    }

}